#pragma once


#ifndef USESHANDLE_H
#define USESHANDLE_H

#include "PKB.h"
#include "spa_types.h"
#include <vector>
#include <set>
#include <string>

using namespace std;


class PKB;

class UsesHandle {

private:
	PKB* pkb;	
	UsesHandle(void);
	~UsesHandle(void);
	UsesHandle(const UsesHandle&);
	UsesHandle& operator=(const UsesHandle&);

	vector<vector<int>> UsesStatementsGivenVar(const VARINDEX);
	vector<vector<int>> UsesAssignmentsGivenVar(const VARINDEX var_index);
	vector<vector<int>> UsesIfGivenVar(const VARINDEX);
	vector<vector<int>> UsesWhileGivenVar(const VARINDEX);
	vector<vector<int>> UsesContainerGivenVar(const VARINDEX);
	vector<vector<int>> UsesStatementsAndVar();
	vector<vector<int>> UsesAssignmentsAndVar();
	vector<vector<int>> UsesIfAndVar();
	vector<vector<int>> UsesWhileAndVar();
	vector<vector<int>> UsesContainerAndVar();
	vector<vector<int>> UsesVarsGivenStatement(const int);
	vector<vector<int>> UsesProcAndVars();
	vector<vector<int>> UsesVarsGivenProc(const PROCINDEX);
	vector<vector<int>> UsesProcGivenVar(const PROCINDEX);
	bool MergeMultiVector(vector<vector<int>> &head, const vector<vector<int>> tail);


public:
	// case 1: Uses(all_s, 'x')
	// case 2: Uses(all_a, 'x')
	// case 3: Uses(all_if, 'x')
	// case 4: Uses(all_while, 'x')
	// *     : Uses(all_container, 'x')  
	// case 5: Uses(all_s, all_v) -- can cache
	// case 6: Uses(all_a, all_v) -- can cache
	// case 7: Uses(all_if, all_v)
	// case 8: Uses(all_while, all_v)
	// *     : Uses(all_container, all_v)
	// case 9: Uses(stmt_num, v)
	// case 10: Uses(p, v)
	// case 11: Uses('Main', v)
	// case 12: Uses(p, 'x')


	//GetStatementsUsesVar
	//GetAssignmentsUsesVar
	//GetIfUsesVar
	//GetWhileUsesVar
	//GetContainerUsesVar
	//GetProcedureUsesVar
	vector<vector<int>> FetchValidUsesStatementVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> FetchValidUsesProcedureVar(vector<int> stmts_in, vector<int> vars_in);
		
	
	vector<vector<int>> GetStatementUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetAssignmentUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetIfUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetWhileUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetContainerUsesVar(vector<int> stmts_in, vector<int> vars_in);
	vector<vector<int>> GetProcedureUsesVar(vector<int> stmts_in, vector<int> vars_in);

	

} ;

#endif
